#include <Arduino.h>
#include <math.h>
#include <algorithm>

#define HX711_SCK 27
#define HX711_DT 26
#define OLED_SDA 19
#define OLED_SCL 18
#define SCREEN_WIDTH 128  //OLED宽度 像素
#define SCREEN_HEIGHT 32  //OLED高度 像素
#define OLED_RESET 4      //重置引脚
#define KEY1 32
#define KEY2 33
#define KEY3 25

#define Mis 0
#define ZeroMis 1
#define MPiN 10
#define HisN 100

double GapValue=482.6;
#define CalibrateWeight 40.75
#define CalN 10

unsigned long Weight_Maopi = 0;
double Weight_Base = 0;
unsigned long HisRead[HisN];  //历史ADC循环队列
int HisFront = 0;
int HisSeg = 0;
int HisRear = 0;
int HisNum = 0;

void HisReadShow() {
  for (int i = 0; i < HisN; i++) {
    if (i == HisFront) Serial.print("[F]");
    else if (i == HisSeg) Serial.print("[S]");
    else if (i == HisRear) Serial.print("[R]");
    else Serial.print("   ");
    Serial.print(HisRead[i]);
    Serial.print("\t");
    if (i == HisN - 1) Serial.print("\n");
  }
  Serial.print(HisFront);
  Serial.print("\t");
  Serial.print(HisSeg);
  Serial.print("\t");
  Serial.print(HisRear);
  Serial.print("\t");
  Serial.print(HisNum);
  Serial.print("\t");
  Serial.println((HisRear - HisSeg + HisN) % HisN);
}
//初始化HX711
void Init_Hx711() {
  pinMode(HX711_SCK, OUTPUT);
  pinMode(HX711_DT, INPUT);
}
//读取HX711
unsigned long HX711_Read(bool recordflag) {
  unsigned long count = 0;
  digitalWrite(HX711_DT, HIGH);
  delayMicroseconds(1);
  digitalWrite(HX711_SCK, LOW);
  delayMicroseconds(1);
  while (digitalRead(HX711_DT))
    ;
  for (unsigned char i = 0; i < 24; i++) {
    digitalWrite(HX711_SCK, HIGH);
    delayMicroseconds(1);
    count = count << 1;
    digitalWrite(HX711_SCK, LOW);
    delayMicroseconds(1);
    if (digitalRead(HX711_DT))
      count++;
  }
  digitalWrite(HX711_SCK, HIGH);
  count ^= 0x800000;
  delayMicroseconds(1);
  digitalWrite(HX711_SCK, LOW);
  delayMicroseconds(1);

  if (recordflag) {
    //更新循环队列
    HisRead[HisRear]=count;
    if (HisNum > 1) {
      while (fabs(double(HisRead[HisSeg]) - double(HisRead[HisRear])) / GapValue > Mis) {
        HisSeg = (HisSeg + 1) % HisN;
      }
    }
    HisRear = (HisRear + 1) % HisN;
    if (HisFront == HisRear) HisFront = (HisFront + 1) % HisN;
    if (HisSeg == HisRear) HisSeg = (HisSeg + 1) % HisN;
    if (HisNum < HisN - 1) HisNum++;
    //HisReadShow();
  }
  //Serial.println(count);
  return count;
}

//称重
double Get_Weight() {
  HX711_Read(true);
  double Weight_Shiwu = 0;
  for (int i = HisSeg; i != HisRear; i = (i + 1) % HisN) {
    Weight_Shiwu += HisRead[i];
  }
  Weight_Shiwu /= (HisRear - HisSeg + HisN) % HisN;
  // if (fabs(double(Weight_Shiwu) - double(Weight_Maopi))/GapValue <= Mis)
  //   Weight_Maopi=Weight_Shiwu;
  if(fabs((double)(Weight_Shiwu - Weight_Maopi) / GapValue)<=ZeroMis) return 0;
  else return (double)(Weight_Shiwu - Weight_Maopi) / GapValue;
}
//获取毛皮重量
void Get_Maopi() {
  //Weight_Maopi = HX711_Read(false);
  Weight_Maopi=0;
  for (int i = 1; i <= MPiN; i++) {
    Weight_Maopi+=HX711_Read(false);
  }
  Weight_Maopi /= MPiN;
}
//计数
void Get_Base() {
  Weight_Base = Get_Weight();
}
int Get_Count() {
  return round(Get_Weight() / Weight_Base);
}

//汉字字符
const unsigned char gImage_jin[38] = { 0x00, 0x10,
                                       0x00, 0xf8,
                                       0x1f, 0x00,
                                       0x10, 0x00,
                                       0x10, 0x00,
                                       0x10, 0x00,
                                       0x1f, 0xfe,
                                       0x10, 0x40,
                                       0x10, 0x40,
                                       0x10, 0x40,
                                       0x10, 0x40,
                                       0x10, 0x40,
                                       0x20, 0x40,
                                       0x20, 0x40,
                                       0x40, 0x40,
                                       0x80, 0x40 };
const unsigned char gImage_ge[38] = { 0x01, 0x00,
                                      0x01, 0x00,
                                      0x02, 0x80,
                                      0x04, 0x40,
                                      0x08, 0x20,
                                      0x10, 0x10,
                                      0x21, 0x08,
                                      0xc1, 0x06,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00,
                                      0x01, 0x00 };
const unsigned char gImage_liang[38] = { 0x00, 0x00,
                                         0xff, 0xfe,
                                         0x04, 0x40,
                                         0x04, 0x40,
                                         0x04, 0x40,
                                         0x7f, 0xfc,
                                         0x44, 0x44,
                                         0x44, 0x44,
                                         0x44, 0x44,
                                         0x4a, 0xa4,
                                         0x4a, 0x94,
                                         0x51, 0x14,
                                         0x42, 0x04,
                                         0x40, 0x04,
                                         0x40, 0x14,
                                         0x40, 0x08 };
const unsigned char gImage_zu[38] = { 0x10, 0x00,
                                      0x11, 0xf8,
                                      0x21, 0x08,
                                      0x21, 0x08,
                                      0x49, 0x08,
                                      0xf9, 0xf8,
                                      0x11, 0x08,
                                      0x21, 0x08,
                                      0x41, 0x08,
                                      0xf9, 0xf8,
                                      0x41, 0x08,
                                      0x01, 0x08,
                                      0x19, 0x08,
                                      0xe1, 0x08,
                                      0x47, 0xfe,
                                      0x00, 0x00 };
const unsigned char gImage_jishu[] = {
    0x00, 0x40, 0x08, 0x20, 
    0x20, 0x40, 0x49, 0x20, 
    0x10, 0x40, 0x2a, 0x20, 
    0x10, 0x40, 0x08, 0x3e, 
    0x00, 0x40, 0xff, 0x44, 
    0x00, 0x40, 0x2a, 0x44, 
    0xf7, 0xfe, 0x49, 0x44, 
    0x10, 0x40, 0x88, 0xa4, 
    0x10, 0x40, 0x10, 0x28, 
    0x10, 0x40, 0xfe, 0x28, 
    0x10, 0x40, 0x22, 0x10, 
    0x10, 0x40, 0x42, 0x10, 
    0x14, 0x40, 0x64, 0x28, 
    0x18, 0x40, 0x18, 0x28, 
    0x10, 0x40, 0x34, 0x44, 
    0x00, 0x40, 0xc2, 0x82
};
const unsigned char gImage_jijia[] = {
    0x00, 0x40, 0x08, 0x40, 
    0x20, 0x40, 0x08, 0x40, 
    0x10, 0x40, 0x08, 0xa0, 
    0x10, 0x40, 0x10, 0xa0, 
    0x00, 0x40, 0x11, 0x10, 
    0x00, 0x40, 0x32, 0x08, 
    0xf7, 0xfe, 0x34, 0x06, 
    0x10, 0x40, 0x51, 0x10, 
    0x10, 0x40, 0x91, 0x10, 
    0x10, 0x40, 0x11, 0x10, 
    0x10, 0x40, 0x11, 0x10, 
    0x10, 0x40, 0x11, 0x10, 
    0x14, 0x40, 0x11, 0x10, 
    0x18, 0x40, 0x12, 0x10, 
    0x10, 0x40, 0x12, 0x10, 
    0x00, 0x40, 0x14, 0x10
};
const unsigned char gImage_yuan[] = {
    0x00, 0x00, 
    0x3f, 0xf8, 
    0x00, 0x00, 
    0x00, 0x00, 
    0x00, 0x00, 
    0xff, 0xfe, 
    0x04, 0x40, 
    0x04, 0x40, 
    0x04, 0x40, 
    0x04, 0x40, 
    0x08, 0x40, 
    0x08, 0x42, 
    0x10, 0x42, 
    0x20, 0x42, 
    0x40, 0x3e, 
    0x80, 0x00
};
const unsigned char gImage_wan[] = {
    0x00, 0x00, 
    0x00, 0x00, 
    0xff, 0xfe, 
    0x04, 0x00, 
    0x04, 0x00, 
    0x04, 0x00, 
    0x07, 0xf0, 
    0x04, 0x10, 
    0x04, 0x10, 
    0x08, 0x10, 
    0x08, 0x10, 
    0x10, 0x10, 
    0x10, 0x10, 
    0x20, 0x10, 
    0x40, 0xa0, 
    0x80, 0x40
};